package com.powerwyx.shortlink.project.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powerwyx.shortlink.project.common.convention.errorcode.BaseErrorCode;
import com.powerwyx.shortlink.project.common.convention.exception.ClientException;
import com.powerwyx.shortlink.project.common.convention.exception.ServiceException;
import com.powerwyx.shortlink.project.mapper.LinkMapper;
import com.powerwyx.shortlink.project.pojo.dto.RecycleBinRecoverDTO;
import com.powerwyx.shortlink.project.pojo.dto.RecycleBinRemoveDTO;
import com.powerwyx.shortlink.project.pojo.dto.RecycleBinSaveDTO;
import com.powerwyx.shortlink.project.pojo.dto.ShortLinkRecycleBinPageDTO;
import com.powerwyx.shortlink.project.pojo.entity.Link;
import com.powerwyx.shortlink.project.pojo.vo.ShortLinkPageVO;
import com.powerwyx.shortlink.project.service.RecycleBinService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import static com.powerwyx.shortlink.project.common.constant.RedisConstant.GOTO_IS_NULL_SHORT_LINK_KEY;
import static com.powerwyx.shortlink.project.common.constant.RedisConstant.GOTO_SHORT_LINK_KEY;

/**
 * @author 王艺锡
 * @version 1.0
 */
@Service
@Slf4j
public class RecycleBinServiceImpl extends ServiceImpl<LinkMapper, Link>
        implements RecycleBinService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 添加短链接至回收站
     * @param recycleBinSaveDTO
     */
    @Override
    public void saveRecycleBin(RecycleBinSaveDTO recycleBinSaveDTO) {
        if(recycleBinSaveDTO == null){
            throw new ServiceException(BaseErrorCode.PARAMS_ERROR);
        }
        //设置要修改的字段
        Link link = Link.builder()
                .enableStatus(1)
                .build();
        boolean isSuccess = update(link, new QueryWrapper<Link>()
                .eq("gid", recycleBinSaveDTO.getGid())
                .eq("full_short_url", recycleBinSaveDTO.getFullShortUrl())
                .eq("enable_status", 0)
                .eq("del_flag", 0));
        if(!isSuccess){
            throw new ClientException(BaseErrorCode.OPERATION_ERROR);
        }

        //删除短链接对应的缓存
        stringRedisTemplate.delete(String.format(GOTO_SHORT_LINK_KEY, recycleBinSaveDTO.getFullShortUrl()));

    }


    /**
     * 将短链接从回收站移出
     * @param recycleBinRecoverDTO
     */
    @Override
    public void recoverRecycleBin(RecycleBinRecoverDTO recycleBinRecoverDTO) {
        if(recycleBinRecoverDTO == null){
            throw new ServiceException(BaseErrorCode.PARAMS_ERROR);
        }
        //设置要修改的字段
        Link link = Link.builder()
                .enableStatus(0)
                .build();
        boolean isSuccess = update(link, new QueryWrapper<Link>()
                .eq("gid", recycleBinRecoverDTO.getGid())
                .eq("full_short_url", recycleBinRecoverDTO.getFullShortUrl())
                .eq("enable_status", 1)
                .eq("del_flag", 0));
        if(!isSuccess){
            throw new ClientException(BaseErrorCode.OPERATION_ERROR);
        }

        //删除可能缓存的空指针
        stringRedisTemplate.delete(String.format(GOTO_IS_NULL_SHORT_LINK_KEY, recycleBinRecoverDTO.getFullShortUrl()));
    }


    /**
     * 根据分组进行分页查询回收站中的短链接
     *
     * @param shortLinkRecycleBinPageDTO
     * @return
     */
    @Override
    public IPage<ShortLinkPageVO> shortLinkRecycleBinPage(ShortLinkRecycleBinPageDTO shortLinkRecycleBinPageDTO) {
        IPage<Link> resultPage = page(shortLinkRecycleBinPageDTO, new QueryWrapper<Link>()
                .in("gid", shortLinkRecycleBinPageDTO.getGidList())
                .eq("enable_status", 1)
                .eq("del_flag", 0)
                .orderByDesc("update_time"));

        return resultPage.convert(link -> {
            ShortLinkPageVO result = BeanUtil.copyProperties(link, ShortLinkPageVO.class);
            result.setDomain("http://" + result.getDomain());
            return result;
        });
    }


    /**
     * 删除回收站短链接
     * @param recycleBinRemoveDTO
     */
    @Override
    public void removeRecycleBin(RecycleBinRemoveDTO recycleBinRemoveDTO) {
        if (recycleBinRemoveDTO == null){
            throw new ClientException(BaseErrorCode.PARAMS_ERROR);
        }

        boolean isSuccess = remove(new QueryWrapper<Link>()
                .eq("gid", recycleBinRemoveDTO.getGid())
                .eq("full_short_url", recycleBinRemoveDTO.getFullShortUrl())
                .eq("enable_status", 1)
                .eq("del_flag", 0));

        if(!isSuccess){
            throw new ClientException(BaseErrorCode.OPERATION_ERROR);
        }

    }

}
